From 35e21c7600ed473885accae8fdb08b96e107a6c4 Mon Sep 17 00:00:00 2001 From: Carl Lerche + Yehuda Katz Date: Thu, 12 Jun 2014 15:51:16 -0700 Subject: [PATCH] Smoke test for git support --- Makefile | 2 +- src/bin/cargo-compile.rs | 2 +- src/cargo/ops/cargo_compile.rs | 1 + src/cargo/sources/git/source.rs | 3 ++ src/cargo/sources/git/utils.rs | 17 +++--- src/cargo/util/result.rs | 12 ++--- tests/{support.rs => support/mod.rs} | 42 ++++++++++++--- tests/support/paths.rs | 46 ++++++++++++++++ tests/test_cargo_compile.rs | 16 +----- tests/test_cargo_compile_git_deps.rs | 79 ++++++++++++++++++++++++++++ tests/tests.rs | 4 +- 11 files changed, 186 insertions(+), 38 deletions(-) rename tests/{support.rs => support/mod.rs} (88%) create mode 100644 tests/support/paths.rs create mode 100644 tests/test_cargo_compile_git_deps.rs diff --git a/Makefile b/Makefile index 0a44bd9f1..edb5b6909 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ $(BIN_TARGETS): target/%: src/bin/%.rs $(HAMMER) $(TOML) $(LIBCARGO) # === Tests -TEST_SRC = $(wildcard tests/*.rs) +TEST_SRC = $(shell find tests -name '*.rs') TEST_DEPS = $(DEPS) -L libs/hamcrest-rust/target target/tests/test-integration: $(HAMCREST) $(TEST_SRC) $(BIN_TARGETS) diff --git a/src/bin/cargo-compile.rs b/src/bin/cargo-compile.rs index b4eae3c0f..fd741c691 100644 --- a/src/bin/cargo-compile.rs +++ b/src/bin/cargo-compile.rs @@ -13,7 +13,7 @@ use hammer::FlagConfig; use cargo::{execute_main_without_stdin,CLIResult,CLIError,ToResult}; use cargo::ops; use cargo::util::important_paths::find_project; -use cargo::util::ToCLI; +use cargo::util::{ToCLI,simple_human}; #[deriving(PartialEq,Clone,Decodable,Encodable)] pub struct Options { diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 072b2bc95..5591b27a5 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -35,6 +35,7 @@ pub fn compile(manifest_path: &Path) -> CargoResult<()> { let sources = try!(sources_for(&package)); + try!(sources.update().wrap("unable to update sources")); let summaries = try!(sources.list().wrap("unable to list packages from source")); let resolved = try!(resolve(package.get_dependencies(), &summaries).wrap("unable to resolve dependencies")); diff --git a/src/cargo/sources/git/source.rs b/src/cargo/sources/git/source.rs index 2e2de1b58..a3872be8e 100644 --- a/src/cargo/sources/git/source.rs +++ b/src/cargo/sources/git/source.rs @@ -37,6 +37,7 @@ impl Show for GitSource { impl Source for GitSource { fn update(&self) -> CargoResult<()> { + log!(5, "updating git source `{}`", self.remote); let repo = try!(self.remote.checkout(&self.db_path)); try!(repo.copy_to(self.reference.as_slice(), &self.checkout_path)); @@ -44,6 +45,7 @@ impl Source for GitSource { } fn list(&self) -> CargoResult> { + log!(5, "listing summaries in git source `{}`", self.remote); let pkg = try!(read_manifest(&self.checkout_path, self.get_namespace())); Ok(vec!(pkg.get_summary().clone())) } @@ -53,6 +55,7 @@ impl Source for GitSource { } fn get(&self, package_ids: &[PackageId]) -> CargoResult> { + log!(5, "getting packages for package ids `{}` from `{}`", package_ids, self.remote); // TODO: Support multiple manifests per repo let pkg = try!(read_manifest(&self.checkout_path, self.remote.get_url())); diff --git a/src/cargo/sources/git/utils.rs b/src/cargo/sources/git/utils.rs index 7218ee41f..4118364cd 100644 --- a/src/cargo/sources/git/utils.rs +++ b/src/cargo/sources/git/utils.rs @@ -67,7 +67,7 @@ macro_rules! errln( * GitRemote represents a remote repository. It gets cloned into a local GitDatabase. */ -#[deriving(PartialEq,Clone)] +#[deriving(PartialEq,Clone,Show)] pub struct GitRemote { url: Url, verbose: bool @@ -170,7 +170,7 @@ impl GitRemote { } fn fetch_into(&self, path: &Path) -> CargoResult<()> { - Ok(git!(*path, self.verbose, "fetch --force --quiet --tags {} refs/heads/*:refs/heads/*", self.url)) + Ok(git!(*path, self.verbose, "fetch --force --quiet --tags {} refs/heads/*:refs/heads/*", self.fetch_location())) } fn clone_into(&self, path: &Path) -> CargoResult<()> { @@ -179,7 +179,14 @@ impl GitRemote { try!(mkdir_recursive(path, UserDir).map_err(|err| human_error(format!("Couldn't recursively create `{}`", dirname.display()), format!("path={}", dirname.display()), io_error(err)))); - Ok(git!(dirname, self.verbose, "clone {} {} --bare --no-hardlinks --quiet", self.url, path.display())) + Ok(git!(dirname, self.verbose, "clone {} {} --bare --no-hardlinks --quiet", self.fetch_location(), path.display())) + } + + fn fetch_location(&self) -> String { + match self.url.scheme.as_slice() { + "file" => self.url.path.clone(), + _ => self.url.to_str() + } } } @@ -254,9 +261,7 @@ impl GitCheckout { } fn git(path: &Path, verbose: bool, str: &str) -> ProcessBuilder { - if verbose { - errln!("Executing git {} @ {}", str, path.display()); - } + debug!("Executing git {} @ {}", str, path.display()); process("git").args(str.split(' ').collect::>().as_slice()).cwd(path.clone()) } diff --git a/src/cargo/util/result.rs b/src/cargo/util/result.rs index e0419e162..8d26fc1a5 100644 --- a/src/cargo/util/result.rs +++ b/src/cargo/util/result.rs @@ -116,14 +116,14 @@ impl CargoError { CargoError { kind: HumanReadableError, desc: BoxedDescription(desc), detail: detail, .. } => { CLIError::new(desc, detail, exit_code) }, - CargoError { kind: InternalError, desc: StaticDescription(desc), detail: None, .. } => { - CLIError::new("An unexpected error occurred", Some(desc), exit_code) + ref err @ CargoError { kind: InternalError, desc: StaticDescription(desc), detail: None, .. } => { + CLIError::new(format!("An unexpected error occurred: {}", err), Some(desc), exit_code) }, - CargoError { kind: InternalError, desc: StaticDescription(desc), detail: Some(detail), .. } => { - CLIError::new("An unexpected error occurred", Some(format!("{}\n{}", desc, detail)), exit_code) + ref err @ CargoError { kind: InternalError, desc: StaticDescription(desc), detail: Some(ref detail), .. } => { + CLIError::new(format!("An unexpected error occurred: {}", err), Some(format!("{}\n{}", desc, detail)), exit_code) }, - _ => { - CLIError::new("An unexpected error occurred", None::<&str>, exit_code) + ref err @ _ => { + CLIError::new(format!("An unexpected error occurred: {}", err), None::<&str>, exit_code) } } } diff --git a/tests/support.rs b/tests/support/mod.rs similarity index 88% rename from tests/support.rs rename to tests/support/mod.rs index ec4f6172d..ac2326ae1 100644 --- a/tests/support.rs +++ b/tests/support/mod.rs @@ -13,7 +13,7 @@ use cargo::core::shell; use cargo::util::{process,ProcessBuilder,CargoError}; use cargo::util::result::ProcessError; -static CARGO_INTEGRATION_TEST_DIR : &'static str = "cargo-integration-tests"; +pub mod paths; /* * @@ -49,7 +49,7 @@ impl FileBuilder { } #[deriving(PartialEq,Clone)] -struct ProjectBuilder { +pub struct ProjectBuilder { name: String, root: Path, files: Vec @@ -64,20 +64,32 @@ impl ProjectBuilder { } } + pub fn join(&self, name: &str, path: T) -> ProjectBuilder { + ProjectBuilder { + name: name.as_slice().to_str(), + root: self.root.join(path.as_slice()).clone(), + files: vec!() + } + } + pub fn root(&self) -> Path { self.root.clone() } - pub fn cargo_process(&self, program: &str) -> ProcessBuilder { - self.build(); - + pub fn process(&self, program: &str) -> ProcessBuilder { process(program) .cwd(self.root()) + .env("HOME", Some(paths::home().display().to_str().as_slice())) + } + + pub fn cargo_process(&self, program: &str) -> ProcessBuilder { + self.build(); + self.process(program) .extra_path(cargo_dir()) } - pub fn file(mut self, path: B, body: &str) -> ProjectBuilder { - self.files.push(FileBuilder::new(self.root.join(path), body)); + pub fn file(mut self, path: B, body: S) -> ProjectBuilder { + self.files.push(FileBuilder::new(self.root.join(path), body.as_slice())); self } @@ -115,7 +127,7 @@ impl ProjectBuilder { // Generates a project layout pub fn project(name: &str) -> ProjectBuilder { - ProjectBuilder::new(name, os::tmpdir().join(CARGO_INTEGRATION_TEST_DIR)) + ProjectBuilder::new(name, paths::root().join(name)) } // === Helpers === @@ -130,6 +142,20 @@ pub fn rmdir_recursive(path: &Path) -> Result<(), String> { .with_err_msg(format!("could not rm directory; path={}", path.display())) } +pub fn main_file(println: T, deps: &[&str]) -> String { + let mut buf = String::new(); + + for dep in deps.iter() { + buf.push_str(format!("extern crate {};\n", dep).as_slice()); + } + + buf.push_str("fn main() { println!("); + buf.push_str(println.as_slice()); + buf.push_str("); }\n"); + + buf.to_str() +} + trait ErrMsg { fn with_err_msg(self, val: String) -> Result; } diff --git a/tests/support/paths.rs b/tests/support/paths.rs new file mode 100644 index 000000000..84013ac6b --- /dev/null +++ b/tests/support/paths.rs @@ -0,0 +1,46 @@ +use std::{io,os}; +use std::io::IoResult; +use std::io::fs; +use cargo::util::realpath; + +static CARGO_INTEGRATION_TEST_DIR : &'static str = "cargo-integration-tests"; + +pub fn root() -> Path { + realpath(&os::tmpdir().join(CARGO_INTEGRATION_TEST_DIR)).unwrap() +} + +pub fn home() -> Path { + root().join("home") +} + +pub trait PathExt { + fn rm_rf(&self) -> IoResult<()>; + fn mkdir_p(&self) -> IoResult<()>; +} + +impl PathExt for Path { + /* Technically there is a potential race condition, but we don't + * care all that much for our tests + */ + fn rm_rf(&self) -> IoResult<()> { + if self.exists() { + fs::rmdir_recursive(self) + } + else { + Ok(()) + } + } + + fn mkdir_p(&self) -> IoResult<()> { + fs::mkdir_recursive(self, io::UserDir) + } +} + +/** + * Ensure required test directories exist and are empty + */ +pub fn setup() { + debug!("path setup; root={}; home={}", root().display(), home().display()); + root().rm_rf().unwrap(); + home().mkdir_p().unwrap(); +} diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 1fad32a04..39cc57026 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -1,4 +1,4 @@ -use support::{ResultTest,project,execs}; +use support::{ResultTest,project,execs,main_file}; use hamcrest::{assert_that,existing_file}; use cargo; use cargo::util::{process,realpath}; @@ -284,18 +284,4 @@ test!(cargo_compile_with_nested_deps_longhand { execs().with_stdout("test passed\n")); }) -fn main_file(println: &str, deps: &[&str]) -> String { - let mut buf = String::new(); - - for dep in deps.iter() { - buf.push_str(format!("extern crate {};\n", dep).as_slice()); - } - - buf.push_str("fn main() { println!("); - buf.push_str(println); - buf.push_str("); }\n"); - - buf.to_str() -} - // test!(compiling_project_with_invalid_manifest) diff --git a/tests/test_cargo_compile_git_deps.rs b/tests/test_cargo_compile_git_deps.rs new file mode 100644 index 000000000..2574a3631 --- /dev/null +++ b/tests/test_cargo_compile_git_deps.rs @@ -0,0 +1,79 @@ +use support::{ProjectBuilder,ResultTest,project,execs,main_file}; +use hamcrest::{assert_that,existing_file}; +use cargo; +use cargo::util::{CargoResult,process}; + +fn setup() { +} + +fn git_repo(name: &str, callback: |ProjectBuilder| -> ProjectBuilder) -> CargoResult { + let mut git_project = project(name); + git_project = callback(git_project); + git_project.build(); + + log!(5, "git init"); + try!(git_project.process("git").args(["init"]).exec_with_output()); + log!(5, "building git project"); + log!(5, "git add ."); + try!(git_project.process("git").args(["add", "."]).exec_with_output()); + log!(5, "git commit"); + try!(git_project.process("git").args(["commit", "-m", "Initial commit"]).exec_with_output()); + Ok(git_project) +} + +test!(cargo_compile_simple_git_dep { + let project = project("foo"); + let git_project = git_repo("dep1", |project| { + project + .file("Cargo.toml", r#" + [project] + + name = "dep1" + version = "0.5.0" + authors = ["carlhuda@example.com"] + + [[lib]] + + name = "dep1" + "#) + .file("src/dep1.rs", r#" + pub fn hello() -> &'static str { + "hello world" + } + "#) + }).assert(); + + let project = project + .file("Cargo.toml", format!(r#" + [project] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.dep1] + + version = "0.5.0" + git = "file://{}" + + [[bin]] + + name = "foo" + "#, git_project.root().display())) + .file("src/foo.rs", main_file(r#""{}", dep1::hello()"#, ["dep1"])); + + let root = project.root(); + let git_root = git_project.root(); + + assert_that(project.cargo_process("cargo-compile"), + execs() + .with_stdout(format!("Compiling dep1 v0.5.0 (file:{})\nCompiling foo v0.5.0 (file:{})\n", + git_root.display(), root.display())) + .with_stderr("")); + + assert_that(&project.root().join("target/foo"), existing_file()); + + assert_that( + cargo::util::process("foo").extra_path(project.root().join("target")), + execs().with_stdout("hello world\n")); +}) diff --git a/tests/tests.rs b/tests/tests.rs index c9dfb93e2..3357e0a62 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -8,16 +8,18 @@ extern crate hamcrest; #[phase(plugin, link)] extern crate log; +mod support; macro_rules! test( ($name:ident $expr:expr) => ( #[test] fn $name() { + ::support::paths::setup(); setup(); $expr; } ) ) -mod support; mod test_cargo_compile; +mod test_cargo_compile_git_deps; mod test_shell; -- 2.30.2